package ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.datatransfer.FlavorListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.lang.model.element.Element;
import javax.swing.JPanel;


public class GamePanel extends JPanel {

	// 1.定义背景图片
	BufferedImage bg;// 背景图

	// 记录子弹的类型
	int num = 1;

	// 创建英雄机对象
	Hero hero = new Hero();

	// 创建敌机的大本营(所有的敌机都放在这里)
	List<Ep> eps = new ArrayList<Ep>();

	// 创建子弹的大本营
	List<Fire> fires = new ArrayList<Fire>();

	// 定义分数
	int score = 0;

	// 设置游戏的开关
	static boolean gameover=true;// 游戏开始时，gameover为false,gameover为true

	// 设置英雄机的火力
	int power = 1;
	
	//设置关卡模式
	int ms=0;
	
	//设置是否出现了boss机
	boolean t=false;
	
	
	/*
	 * 开始游戏的方法
	 */
	public void action() {
		
		new Thread() {
			public void run() {
				// 写入一个死循环，让游戏一直运行
				
				while (true) {
					System.out.println(gameover);
					if (!gameover) {
						
						try {

							System.out.println("游戏正在运行2");
							// 调用敌机入场的方法
							epEnter();

							// 调用让敌机移动的方法
							epMove();

							// 发射子弹
							shoot();

							// 让子弹移动
							fireMove();

							// 打飞机的方法
							shootEp();

							// 判断敌机是否撞到了英雄机
							hit();

							System.out.println("游戏正在运行3");

							// 线程休眠 sleep(毫秒数)
							Thread.sleep(20);

						} catch (IOException | InterruptedException e) {
							e.printStackTrace();
						}
						
						// 重绘，刷新
						repaint();
					}
				}
			}
		}.start();
	}

	

	
	/*
	 * 检测敌机是否撞到了英雄机的方法
	 */
	protected void hit() {
		// 遍历敌机
		for (int i = 0; i < eps.size(); i++) {
			// 获取一个敌机
			Ep e = eps.get(i);
			// 如果敌机被英雄机撞上了
			if (e.hitBy(hero)) {
				// 1.删除敌机
				eps.remove(i);
				// 2.英雄机的血量减少
				hero.hp--;
				// 英雄机的火力为1
				power = 1;
				// 子弹类型为1
				num = 1;
				// 3.增加分数
				score += 5;
				// 4.当英雄机的血量减少到0时，游戏结束
				if (hero.hp <= 0) {
					// 游戏结束
					gameover = true;
					//关卡清0
					ms=0;
				}
			}
		}

	}

	/*
	 * 检测子弹是否击中敌机 是否所有的敌机都有可能被子弹击中（排除移出屏幕的）（true or false） 所有的子弹都有可能打到敌机
	 */
	protected void shootEp() {
		// 遍历所有的子弹
		for (int i = 0; i < fires.size(); i++) {
			// 获取每一颗子弹
			Fire fire = fires.get(i);
			// 每拿一个子弹，就判断一下这颗子弹是否击中了敌机
			bang(fire);
		}
	}

	
	/*
	 * 判断一颗子弹是否击中了敌机
	 */
	private void bang(Fire fire) {
		// 遍历所有的敌机
		for (int i = 0; i < eps.size(); i++) {
			// 获取每一个敌机
			Ep e = eps.get(i);
			// 判断该子弹是否击中敌机
			if (e.shootBy(fire)) {
				// 如果敌机被子弹击中

				// 如果不是导弹
				if (e.type != 15) {
					// 1.让敌机的血量减少
					e.hp=e.hp-fire.fr;
					// 当敌机的血量减少到零时，死亡
					if (e.hp <= 0) {
						// 判断敌机是否是道具机
						if (e.type == 12) {
							// 增加火力值
							power++;
							// 如果power值大于3,增加血量
							if (power > 3) {
								hero.hp++;
								if (hero.hp > 5) {
									hero.hp = 5;
								}
								if (num == 1) {
									num = 2;
									power=1;
								} else if (num == 2) {
									num = 3;
									power=1;
								} else if(num==3) {
									num=4;
									power=4;
								}
							      
							}
						}
							// 2.敌机死亡（消失：从敌机大本营中删除）
							eps.remove(e);
							// 3.增加分数
							score =e.type+ score;
							//4.消灭的敌机数
							Ep.number++;
							
					}

					// 4.子弹消失：从子弹库中删除
					if(num!=4) {
					fires.remove(fire);
					}

				}
			}
		}
	}

	/*
	 * 子弹移动的方法
	 */
	protected void fireMove() {
		// 遍历所有子弹
		for (int i = 0; i < fires.size(); i++) {
			// 获取每一颗子弹
			Fire fire = fires.get(i);
			// 让子弹移动
			fire.move();
		}

	}

	/*
	 * 发射子弹的方法
	 */
	int findex = 0;// 记录shoot方法执行的次数

	protected void shoot() throws IOException {
		findex++;
		if (findex == 20) {
			if (power == 1) {

				// 创建子弹
				Fire fire3 = new Fire(hero.x + 40, hero.y, 1, num);
				// 将子弹加入到弹药库中
				fires.add(fire3);

			} else if (power == 2) {

				// 创建子弹
				Fire fire1 = new Fire(hero.x + 10, hero.y, 1, num);
				// 将子弹加入到弹药库中
				fires.add(fire1);
				// 创建子弹

				Fire fire2 = new Fire(hero.x + 80, hero.y, 1, num);
				// 将子弹加入到弹药库中
				fires.add(fire2);
				// 创建子弹

			} else if (power == 3) {
				
				// 创建子弹
				Fire fire1 = new Fire(hero.x , hero.y, 0, num);
				// 将子弹加入到弹药库中
				fires.add(fire1);
				// 创建子弹
				Fire fire2 = new Fire(hero.x + 50, hero.y - 20, 1, num);
				// 将子弹加入到弹药库中
				fires.add(fire2);
				// 创建子弹
				Fire fire3 = new Fire(hero.x + 100, hero.y, 2, num);
				// 将子弹加入到弹药库中
				fires.add(fire3);

			} else if (power == 4) {
				
				// 创建子弹
				Fire fire1 = new Fire(hero.x+15, hero.y, 0, num);
				// 将子弹加入到弹药库中
				fires.add(fire1);
				// 创建子弹
				Fire fire2 = new Fire(hero.x , hero.y - 20, 1, num);
				// 将子弹加入到弹药库中
				fires.add(fire2);
				// 创建子弹
				Fire fire3 = new Fire(hero.x + 70, hero.y, 2, num);
				// 将子弹加入到弹药库中
				fires.add(fire3);
				
				//power置为1
				power=1;
				num=3;
			}
			
			findex = 0;// 计数器归零
		}
	}

	/*
	 * 敌机入场的方法 因为此方法在死循环中调用的，所以该方法会一直重复执行
	 */
	int index = 0;// 记录方法执行的次数，每执行n次，释放一次敌机

	protected void epEnter() throws IOException {
		// 记录执行的次数
		// 用index的大小来设置关卡模式
		// 默认关卡模式是0
		index++;
		if(index==(40-ms*10)) {
			//创建敌机
			Ep e = new Ep();
			// 将敌机加入到敌机大本营中
			eps.add(e);
			index=0;
		    }
		}



	

	/*
	 * 敌机移动的方法
	 */
	protected void epMove() {
		// 遍历所有的敌机
		for (int i = 0; i < eps.size(); i++) {
			// 获取每一个敌机
			Ep ep = eps.get(i);
			ep.move();
		}
	}

	/*
	 * 构造方法：确定面板的的特点
	 */
	public GamePanel(Frame frame) throws IOException {
		// 设置背景
		setBackground(Color.pink);
		// 初始化图片
		bg = App.getImg("/img/bg2.jpg");

		// 创建鼠标监听器
		MouseAdapter adapter = new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// 点击鼠标时，会执行的代码
				
				// 如果游戏结束了，点击屏幕时重新开始游戏
				//当游戏结束时，读取鼠标的按压位置
				if(gameover&&ms==0) {
				int x=e.getX();
				int y=e.getY();
				System.out.println(x+","+y);
				if(y>=500&&y<550&&x>=100&&x<400) {
					ms=1;
				}else if(y>=550&&y<600&&x>=100&&x<400) {
					ms=2;
				}else if(y>=600&&y<650&&x>=100&&x<400) {
					ms=3;
				}
				System.out.println(gameover);
				System.out.println(ms);
				
				// 刷新界面
				repaint();
				}
				
				
				if (gameover&&ms!=0) {

					// 重新开始游戏
					// 重新创建敌机的大本营(所有的敌机都放在这里)
					eps = new ArrayList<Ep>();

					// 重新创建英雄机
					try {
						hero = new Hero();
					} catch (IOException e2) {
						
						e2.printStackTrace();
					}

					// 清空敌机集合
					eps.clear();

					// 清空子弹集合
					fires.clear();

					// 重置游戏开关
					gameover = false;

					// 分数清0
					score = 0;

					// 火力值清1
					power = 1;

					//子弹类型清1
					num = 1;
					
					//消灭敌机数清0
					Ep.number=1;
					
					//清空敌机出现数量
					Ep.Appearnumber=1;

					System.out.println(gameover);

					// 随机背景图
					Random random = new Random();
					int index = random.nextInt(5) + 1;

					try {
						bg = App.getImg("/img/bg" + index + ".jpg");
					} catch (IOException e1) {
						
						e1.printStackTrace();
					}

					// 刷新界面
					repaint();
				}
			}

			@Override
			public void mouseMoved(MouseEvent e) {
				// 当鼠标在游戏界面中移动时，会触发方法
				// 让英雄机跟着鼠标一起移动
				// 让英雄机的横纵坐标等于鼠标的横纵坐标
				// 获取鼠标的横纵坐标
				int max = e.getX();// 获取鼠标的横坐标
				int may = e.getY();// 获取鼠标的纵坐标
				// 如果游戏没有结束
				if (!gameover) {
					// 让英雄机移动到鼠标的坐标上（英雄机的行为，可以在英雄机中定义移动到鼠标坐标位置的方法）
					hero.moveToMouse(max, may);
					// 刷新界面，将英雄机绘制到新的位置上
					// 重新调用paint方法
					repaint();
				}
			}
			
		};

		// 3.将适配器加入到监听器中
		addMouseListener(adapter);
		addMouseMotionListener(adapter);
	}


	@Override
	public void paint(Graphics g) {
		super.paint(g);
		// 画图片
		// g.drawImage(图片，图片的横坐标，图片的纵坐标，null);
		g.drawImage(bg, 0, 0, 512, 768, null);

		// 画英雄机
		// g.drawImage(图片,图片的横坐标,图片的纵坐标,图片的宽度，图片的高度，null);
		g.drawImage(hero.img, hero.x, hero.y, hero.w, hero.h, null);

		// 画敌机
		// 遍历集合，画出所有的敌机
		for (int i = 0; i < eps.size(); i++) {
			// 获取每一个敌机
			Ep ep = eps.get(i);
			g.drawImage(ep.img, ep.x, ep.y, ep.w, ep.h, null);
			//如果敌机超出界面，就从集合删除
			if(ep.h>768) {
				eps.remove(i);
			}
		}

		// 画子弹
		// 遍历集合，画出所有的敌机
		for (int i = 0; i < fires.size(); i++) {
			// 获取每一个子弹
			Fire fire = fires.get(i);
			g.drawImage(fire.img, fire.x, fire.y, fire.w, fire.h, null);

		}
		
		// 画BOSS机出现倒计时
		g.setColor(Color.green);
		g.setFont(new Font("楷体", Font.BOLD, 20));
		g.drawString("BOSS机出现倒计时："+(81-Ep.Appearnumber%80), 10,30);
		
		// 画消灭敌机数
		g.setColor(Color.red);
		g.setFont(new Font("楷体", Font.BOLD, 20));
		g.drawString("消灭敌机数："+(Ep.number-1), 10, 50);
		
		// 画子弹类型
		g.setColor(Color.green);
		g.setFont(new Font("楷体", Font.BOLD, 20));
		g.drawString("子弹类型:" + num, 10, 70);
		
		// 画火力值
		g.setColor(Color.red);
		g.setFont(new Font("楷体", Font.BOLD, 20));
		g.drawString("火力值:" + power, 10, 90);

		// 画分数
		g.setColor(Color.white);
		g.setFont(new Font("楷体", Font.BOLD, 20));
		g.drawString("分数:" + score, 10, 110);

				
		
		
		// 画游戏类型
		String str="";
		if(ms==0) {
			str="默认模式";
		}else if(ms==1) {
			str="简单模式";
		}else if(ms==2) {
			str="普通模式";
		}else if(ms==3) {
			str="困难模式";
		}
		g.setColor(Color.black);
		g.setFont(new Font("楷体", Font.BOLD, 30));
		g.drawString(str, 200, 720);

		

		// 画英雄机的血量
		for (int i = 0; i < hero.hp; i++) {
			g.drawImage(hero.img, 300 + i * 35, 5, 30, 30, null);
		}

		// 当游戏结束时，画出GameOver
		if (gameover) {
			
			//画游戏登陆时的界面
			try {
				bg = App.getImg("/img/face.png");
			} catch (IOException e) {
				e.printStackTrace();
			}
			g.drawImage(bg, 0 ,  0, 512, 728,  null);
			
			//选择关卡模式(鼠标点击相应的位置进行操作)
			g.setColor(Color.black);
			g.setFont(new Font("楷体", Font.BOLD, 30));
			g.drawString("请选择关卡模式：", 130, 450);
			g.drawString("(鼠标点击相应的位置进行操作)", 40, 480);
			
			g.setColor(Color.blue);
			g.setFont(new Font("楷体", Font.BOLD, 50));
			g.drawString("1、简单模式", 100, 550);
			g.drawString("2、普通模式" , 100, 600);
			g.drawString("3、困难模式" , 100, 650);
			
		}
	}
}
